"""
症状自查小程序API测试用例
"""

import unittest
from unittest.mock import Mock, patch
import sys
import os

# 添加当前目录到Python路径
sys.path.append(os.path.dirname(os.path.abspath(__file__)))

from symptom_checker_api import SymptomCheckerAPI, AdvancedSymptomCheckerAPI


class TestSymptomCheckerAPI(unittest.TestCase):
    """基础API测试类"""
    
    def setUp(self):
        """测试前准备"""
        self.api = SymptomCheckerAPI("https://test-api.symptom-checker.com/v1")
    
    def test_init(self):
        """测试API客户端初始化"""
        self.assertEqual(self.api.base_url, "https://test-api.symptom-checker.com/v1")
        self.assertIsNone(self.api.token)
        self.assertIsNotNone(self.api.session)
    
    @patch('symptom_checker_api.requests.Session.request')
    def test_login_success(self, mock_request):
        """测试成功登录"""
        # 模拟成功响应
        mock_response = Mock()
        mock_response.json.return_value = {
            "code": 200,
            "data": {
                "token": "test_jwt_token_123",
                "user_id": "user_123",
                "user_type": "client",
                "expires_in": 3600
            }
        }
        mock_response.raise_for_status.return_value = None
        mock_request.return_value = mock_response
        
        # 执行登录
        result = self.api.login("test_user", "password123")
        
        # 验证结果
        self.assertTrue(result)
        self.assertEqual(self.api.token, "test_jwt_token_123")
        mock_request.assert_called_once()
    
    @patch('symptom_checker_api.requests.Session.request')
    def test_login_failure(self, mock_request):
        """测试登录失败"""
        # 模拟失败响应
        mock_response = Mock()
        mock_response.json.return_value = {
            "code": 401,
            "message": "用户名或密码错误"
        }
        mock_response.raise_for_status.return_value = None
        mock_request.return_value = mock_response
        
        # 执行登录
        result = self.api.login("wrong_user", "wrong_password")
        
        # 验证结果
        self.assertFalse(result)
        self.assertIsNone(self.api.token)
    
    @patch('symptom_checker_api.requests.Session.request')
    def test_get_symptoms(self, mock_request):
        """测试获取症状列表"""
        # 模拟症状数据
        mock_response = Mock()
        mock_response.json.return_value = {
            "code": 200,
            "data": {
                "symptoms": [
                    {
                        "id": "fever",
                        "name": "发烧",
                        "description": "体温升高",
                        "category": "general",
                        "severity": 2
                    },
                    {
                        "id": "cough",
                        "name": "咳嗽",
                        "description": "呼吸道症状",
                        "category": "respiratory",
                        "severity": 1
                    }
                ]
            }
        }
        mock_response.raise_for_status.return_value = None
        mock_request.return_value = mock_response
        
        # 设置token（模拟已登录状态）
        self.api.token = "test_token"
        
        # 获取症状列表
        symptoms = self.api.get_symptoms()
        
        # 验证结果
        self.assertEqual(len(symptoms), 2)
        self.assertEqual(symptoms[0]["id"], "fever")
        self.assertEqual(symptoms[1]["name"], "咳嗽")
    
    @patch('symptom_checker_api.requests.Session.request')
    def test_diagnose(self, mock_request):
        """测试诊断功能"""
        # 模拟诊断结果
        mock_response = Mock()
        mock_response.json.return_value = {
            "code": 200,
            "data": {
                "possible_conditions": ["普通感冒", "流感"],
                "probability": 0.75,
                "advice": "多休息，多喝水",
                "emergency_level": 2,
                "diagnosis_id": "diag_123"
            }
        }
        mock_response.raise_for_status.return_value = None
        mock_request.return_value = mock_response
        
        # 设置token
        self.api.token = "test_token"
        
        # 执行诊断
        selected_symptoms = ["fever", "cough"]
        result = self.api.diagnose(selected_symptoms, "user_123", "感觉不舒服")
        
        # 验证结果
        self.assertIn("普通感冒", result["possible_conditions"])
        self.assertEqual(result["probability"], 0.75)
        self.assertEqual(result["emergency_level"], 2)
    
    @patch('symptom_checker_api.requests.Session.request')
    def test_get_diagnosis_history(self, mock_request):
        """测试获取诊断历史"""
        # 模拟历史数据
        mock_response = Mock()
        mock_response.json.return_value = {
            "code": 200,
            "data": {
                "records": [
                    {
                        "id": "record_1",
                        "selected_symptoms": ["fever", "cough"],
                        "diagnosis_result": {
                            "possible_conditions": ["普通感冒"],
                            "probability": 0.8,
                            "advice": "建议内容",
                            "emergency_level": 2
                        },
                        "timestamp": "2024-01-01T10:00:00Z"
                    }
                ]
            }
        }
        mock_response.raise_for_status.return_value = None
        mock_request.return_value = mock_response
        
        # 设置token
        self.api.token = "test_token"
        
        # 获取历史记录
        history = self.api.get_diagnosis_history("user_123")
        
        # 验证结果
        self.assertEqual(len(history), 1)
        self.assertEqual(history[0]["id"], "record_1")
        self.assertEqual(history[0]["selected_symptoms"], ["fever", "cough"])


class TestAdvancedSymptomCheckerAPI(unittest.TestCase):
    """高级API测试类"""
    
    def setUp(self):
        """测试前准备"""
        self.advanced_api = AdvancedSymptomCheckerAPI("https://test-api.symptom-checker.com/v1")
    
    @patch.object(AdvancedSymptomCheckerAPI, 'diagnose')
    def test_batch_diagnose(self, mock_diagnose):
        """测试批量诊断"""
        # 模拟单个诊断结果
        mock_diagnose.return_value = {
            "possible_conditions": ["测试疾病"],
            "probability": 0.8,
            "advice": "测试建议",
            "emergency_level": 1
        }
        
        # 准备批量数据
        users_data = [
            {"user_id": "user1", "symptoms": ["fever", "cough"]},
            {"user_id": "user2", "symptoms": ["headache"]},
            {"user_id": "user3", "symptoms": ["fatigue", "nausea"]}
        ]
        
        # 执行批量诊断
        results = self.advanced_api.batch_diagnose(users_data)
        
        # 验证结果
        self.assertEqual(len(results), 3)
        self.assertEqual(results[0]["user_id"], "user1")
        self.assertEqual(results[1]["user_id"], "user2")
        self.assertEqual(results[2]["user_id"], "user3")
        
        # 验证每个结果都有正确的状态
        for result in results:
            self.assertIn("status", result)
            self.assertIn("timestamp", result)
            self.assertIn("result", result)
    
    @patch.object(AdvancedSymptomCheckerAPI, 'get_diagnosis_history')
    def test_export_diagnosis_history_json(self, mock_history):
        """测试导出JSON格式的诊断历史"""
        # 模拟历史数据
        mock_history.return_value = [
            {
                "id": "record_1",
                "selected_symptoms": ["fever", "cough"],
                "diagnosis_result": {
                    "possible_conditions": ["普通感冒"],
                    "probability": 0.8,
                    "advice": "建议内容",
                    "emergency_level": 2
                },
                "timestamp": "2024-01-01T10:00:00Z"
            }
        ]
        
        # 执行导出
        import tempfile
        import os
        
        with tempfile.NamedTemporaryFile(mode='w', suffix='.json', delete=False) as temp_file:
            temp_filename = temp_file.name
        
        try:
            result = self.advanced_api.export_diagnosis_history("user_123", temp_filename, "json")
            
            # 验证导出成功
            self.assertTrue(result)
            
            # 验证文件存在且内容正确
            self.assertTrue(os.path.exists(temp_filename))
            
            import json
            with open(temp_filename, 'r', encoding='utf-8') as f:
                exported_data = json.load(f)
            
            self.assertEqual(len(exported_data), 1)
            self.assertEqual(exported_data[0]["id"], "record_1")
            
        finally:
            # 清理临时文件
            if os.path.exists(temp_filename):
                os.unlink(temp_filename)
    
    @patch.object(AdvancedSymptomCheckerAPI, 'get_symptoms')
    def test_search_symptoms_by_keyword(self, mock_get_symptoms):
        """测试关键词搜索症状"""
        # 模拟症状数据
        mock_get_symptoms.return_value = [
            {
                "id": "headache",
                "name": "头痛",
                "description": "头部疼痛不适",
                "category": "neurological",
                "severity": 2
            },
            {
                "id": "stomachache",
                "name": "胃痛",
                "description": "胃部不适",
                "category": "digestive",
                "severity": 1
            },
            {
                "id": "back_pain",
                "name": "背痛",
                "description": "背部疼痛",
                "category": "musculoskeletal",
                "severity": 2
            }
        ]
        
        # 搜索"痛"关键词
        results = self.advanced_api.search_symptoms_by_keyword("痛")
        
        # 验证结果
        self.assertEqual(len(results), 3)  # 所有症状都包含"痛"字
        
        # 搜索"头痛"关键词
        results = self.advanced_api.search_symptoms_by_keyword("头痛")
        self.assertEqual(len(results), 1)
        self.assertEqual(results[0]["id"], "headache")
        
        # 搜索不存在的关键词
        results = self.advanced_api.search_symptoms_by_keyword("不存在")
        self.assertEqual(len(results), 0)


class TestErrorHandling(unittest.TestCase):
    """错误处理测试类"""
    
    def setUp(self):
        """测试前准备"""
        self.api = SymptomCheckerAPI("https://test-api.symptom-checker.com/v1")
    
    @patch('symptom_checker_api.requests.Session.request')
    def test_network_timeout(self, mock_request):
        """测试网络超时处理"""
        import requests
        
        # 模拟超时异常
        mock_request.side_effect = requests.exceptions.Timeout("请求超时")
        
        # 执行请求并验证异常
        with self.assertRaises(requests.exceptions.Timeout):
            self.api.login("test_user", "password123")
    
    @patch('symptom_checker_api.requests.Session.request')
    def test_http_error(self, mock_request):
        """测试HTTP错误处理"""
        import requests
        
        # 模拟HTTP错误
        mock_response = Mock()
        mock_response.status_code = 500
        mock_request.side_effect = requests.exceptions.HTTPError(response=mock_response)
        
        # 执行请求并验证异常
        with self.assertRaises(requests.exceptions.HTTPError):
            self.api.login("test_user", "password123")


def run_tests():
    """运行所有测试"""
    # 创建测试套件
    loader = unittest.TestLoader()
    suite = unittest.TestSuite()
    
    # 添加测试类
    suite.addTests(loader.loadTestsFromTestCase(TestSymptomCheckerAPI))
    suite.addTests(loader.loadTestsFromTestCase(TestAdvancedSymptomCheckerAPI))
    suite.addTests(loader.loadTestsFromTestCase(TestErrorHandling))
    
    # 运行测试
    runner = unittest.TextTestRunner(verbosity=2)
    result = runner.run(suite)
    
    # 返回测试结果
    return result.wasSuccessful()


if __name__ == "__main__":
    # 运行测试
    success = run_tests()
    
    if success:
        print("\n✅ 所有测试通过！")
    else:
        print("\n❌ 部分测试失败！")
    
    sys.exit(0 if success else 1)